<?php

/*
	Class: Auth

	About: Author
		J William McCarthy

	About: License
		<http://communit.as/docs/license>

	About: See Also
		<App_Controller_Action_Abstract>
*/
class AuthController extends App_Controller_Action_Abstract {

	/* Group: Actions */

	/*
		Function: login
			Either displays a login form, processes a login request, or
			automatically logs someone in (if auto_login in the app variables is set to true).

		Plugin Hooks:
			- *auth_login_login_success* (action) - Enables you to perform custom actions before the browser is redirected if the login attempt succeeds.
				param username - The username of the user logging in.
				param password - The password of the user logging in.
				param requested_url - The URL to redirect to after login success and after the plugin has executed.
			- *auth_login_login_failure* (action) - Enables you to perform custom actions if the login attempt failed.
				param username - The username of the user logging in.

		View Variables:
			$errors - An array of error messages. Only present if errors occurred.
			$last_login - The username of the last user to log in, or null if there was a failed login.
			$pagetitle - The HTML page title.
	*/
    function loginAction(){
    	$appNamespace = new Zend_Session_Namespace('App_Temp');
        $frontcontroller = Zend_Controller_Front::getInstance();
        $request = $frontcontroller->getRequest();
         if ($this->getRequest()->isPost() or $appNamespace->autoLogin){
            // collect the data from the user
            $filter = new Zend_Filter_StripTags();
            $appNamespace = new Zend_Session_Namespace('App_Temp');
		   if($appNamespace->autoLogin){
            	$autologin = true;
            	$username = $appNamespace->autoLoginUsername;
        		$password = $appNamespace->autoLoginPassword;
        		$appNamespace->autoLogin = null;
        		$appNamespace->autoLoginUsername = null;
        		$appNamespace->autoLoginPassword = null;
            } else {
            	$username = $filter->filter($this->_request->getPost('username'));
            	$plain_password = $filter->filter($this->_request->getPost('password'));
            	$password = md5($plain_password);
            }
            // setup Zend_Auth adapter for a database table

            $dbAdapter = Zend_Db_Table::getDefaultAdapter();
            $authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);
            $authAdapter->setTableName('default_users');
            $authAdapter->setIdentityColumn('username');
            $authAdapter->setCredentialColumn('password');

            // Set the input credential values to authenticate against
            $authAdapter->setIdentity($username);
            $authAdapter->setCredential($password);

            // do the authentication
            $auth = Zend_Auth::getInstance();
            try{
            	$result = $auth->authenticate($authAdapter);

	            if ($result->isValid()) {
	            	$appNamespace->last_login = $username;
	                // success : store database row to auth's storage system
	                // (not the password though!)
	                $data = $authAdapter->getResultRowObject(null, 'password');
	                $auth->getStorage()->write($data);
	                Zend_Loader::loadClass('Zend_Session');
            		$defaultNamespace = new Zend_Session_Namespace('Zend_Auth');
	                $defaultNamespace->setExpirationSeconds(86400);

	                //update user last_login_on
	                $users_table = new Users();
	                $where = $users_table->getAdapter()->quoteInto('username = ?', $username);
	                $users_table->update(array('last_login_on' => date(DB_DATETIME_FORMAT)), $where);
	                $params = array('username' => $username,'password' => $plain_password);
	                if(isset($appNamespace->requestedUrl)){
	                	$params['requested_url'] = $appNamespace->requestedUrl;
	                } else {
	                	$params['requested_url'] = null;
	                }

	                $this->_app_plugin->doAction($this->_mca . '_login_success', $params); // ACTION HOOK

					if(isset($appNamespace->requestedUrl)){
						$this->_redirect($appNamespace->requestedUrl);
					} else {
						// get the last viewed page, or default to the logged in user's profile page
						$this->_redirect(App_Common::getViewState($this->session, 'last_visited', "/profile/" . $username));
					}
	            } else {
	                // failure: clear database row from session
	                $appNamespace->last_login = null;
	                $this->view->errors = array('Login failed.');
	                $params = array('username' => $username);
	                $this->_app_plugin->doAction($this->_mca . '_login_failure', $params); // ACTION HOOK
	            }
            } catch (Exception $e){
            	$appNamespace->last_login = null;
            	$this->view->errors = array('Login failed.');
            }
        }
        $this->view->pagetitle = "Log In";
        $this->view->last_login = $appNamespace->last_login;
    }

	/*
		Function: denied
			This page is shown if the user is not allowed access to the requested page.
			It's typically reached via HTTP Response Redirect.

		Plugin Hooks:
			- *auth_denied* (action) - Allows you to perform actions just before the page renders.
				param username - The username of the logged-in user. Only exists if there is a logged-in user.
	*/
    function deniedAction(){
    	$this->view->pagetitle = "Access Denied";
    	$this->view->message = "You are not authorized to perform this action.";
    	$params = array();
    	if($this->_auth->hasIdentity()){
    		$params['username'] = $this->_identity->username;
    	}
    	$this->_app_plugin->doAction($this->_mca, $params); // ACTION HOOK
    }

	/*
		Function: missing
			This page is shown if the requested page does not exist.
			It's typically reached via HTTP Response Redirect.

		Plugin Hooks:
			- *auth_missing* (action) - Allows you to perform actions just before the page renders.
				param username - The username of the logged-in user. Only exists if there is a logged-in user.
	*/
	function missingAction(){
		$params = array();
		$params['username'] = null;
    	if($this->_auth->hasIdentity()){
    		$users_table = new Users();
    		$user = $users_table->fetchByUsername($this->_identity->username);
    		if(!is_null($user)){
    			$this->view->user = $user->toArray();
    			$params['username'] = $user->username;
    		}
    	}
    	$this->_app_plugin->doAction($this->_mca, $params); // ACTION HOOK
    }

	/*
		Function: logout
			Logs a user out of their session and redirects to the the app root ('/', currently hardcoded).

		Plugin Hooks:
			- *auth_logout_pre* (action) - Allows you to perform actions before the user is logged out.
				param username - The username of the logged-in user. Only exists if there is a logged-in user.
			- *auth_logout_post* (action) - Allows you to perform actions after the user is logged out and before the page is redirected. You could override the redirect here.
				param username - The username of the logged-in user. Only exists if there is a logged-in user.
	*/
    function logoutAction(){
    	$appNamespace = new Zend_Session_Namespace('App_Temp');
    	$appNamespace->requestedUrl = null;
    	$params = array();
    	$params['username'] = null;
    	if($this->_auth->hasIdentity()){
    		$params['username'] = $this->_identity->username;
    	}
    	$this->_app_plugin->doAction($this->_mca . '_pre', $params); // ACTION HOOK
        Zend_Auth::getInstance()->clearIdentity();
        $this->_app_plugin->doAction($this->_mca . '_post', $params); // ACTION HOOK
        $this->_redirect('/');
    }

	/*
		Function: error

		Plugin Hooks:
			- *auth_error* (action) - Allows you to perform an action any time an error occurs.
	*/
    function errorAction(){
    	$this->_app_plugin->doAction($this->_mca, array()); // ACTION HOOK
    }

}
